package com.k.base.jdk.proxy.demo2.frm;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * dynamic proxy
 *
 * @author k
 */
public class InterfaceImplObjectInvocationHandler<T extends ProxyAction> implements InvocationHandler {
    private final Object interfaceImpl;
    private final T action;
    public InterfaceImplObjectInvocationHandler(Object targetInterfaceImpl, T action){
        this.interfaceImpl = targetInterfaceImpl;
        this.action = action;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        Throwable throwable = null;
        try{
            before(proxy,method,args);
            result = method.invoke(interfaceImpl,args);
            after(proxy,method,args,result);
        }catch (Exception e){
            exception(proxy,method,args);
            throwable = e;
        }
        afterReturn(proxy,method,args,result);
        if(throwable!=null){
            throw throwable;
        }
        return result;
    }
    // 以下方法调用用户编写的方法,异常无法处理,也不能抛出(抛出影响被代理方法逻辑了),所以打印,不考虑客户代码异常,不能受客户代码影响
    void before(Object proxy, Method method, Object[] args){
        try {
            action.before(proxy,method,args);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    void after(Object proxy, Method method, Object[] args,Object result){
        try {
            action.after(proxy,method,args,result);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    void exception(Object proxy, Method method, Object[] args){
        try {
            action.exception(proxy,method,args);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    void afterReturn(Object proxy, Method method, Object[] args,Object result){
        try {
            action.afterReturn(proxy,method,args,result);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
